package com.sky.service.impl;


import com.alibaba.fastjson.JSON;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;

import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.CategoryService;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Override
    //根据id删除分类
    public void deleteById(Long id) {
        Integer count1= dishMapper.countByCategoryId(id);
        if(count1>0){
            throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_DISH);
        }
        Integer count2 = setmealMapper.countByCategoryId(id);
        if(count2>0){
            throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_SETMEAL);
        }
        categoryMapper.deleteById(id);
        stringRedisTemplate.opsForHash().delete("category:type:"+null,id.toString());
    }

    @Override
    //添加分类
    public void insert(CategoryDTO categoryDTO) {
        String key="category:type:"+null;
        Category category = new Category();
        BeanUtils.copyProperties(categoryDTO,category);
        category.setStatus(StatusConstant.DISABLE);
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        categoryMapper.insert(category);
        //添加缓存
        stringRedisTemplate.opsForHash().put(key,category.getId().toString(),JSON.toJSONString(category));
    }

    @Override
    //分页查询
    public PageResult sleectPageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {

        PageHelper.startPage(categoryPageQueryDTO.getPage(),categoryPageQueryDTO.getPageSize());
        Page<Category> page=categoryMapper.selectPageQuery(categoryPageQueryDTO);
        return new PageResult(page.getTotal(),page.getResult());
    }

    @Override
    //修改分类
    public void update(CategoryDTO categoryDTO) {
        Category category = new Category();
        BeanUtils.copyProperties(categoryDTO,category);
        Integer type= categoryMapper.selectTypeById(categoryDTO.getId());
        categoryMapper.update(category);
        //删除缓存
        stringRedisTemplate.opsForHash().delete("category:type:"+null,categoryDTO.getId().toString());
    }
    @Override
    public List<Category> selectByType(Integer type) {
         //1.判断type,是否为空
        //2.缓存key
        String key="category:type:"+type;
           //查询缓存
        List<Object> values = stringRedisTemplate.opsForHash().values(key);
        //获取缓存的数据数量
        int size = values.size();

        int categoryNum= categoryMapper.countCategory(type);
        if(size==categoryNum){
            //缓存数据存在且一致
            List<Category> categoryList = values.stream()
                    .map(value -> JSON.parseObject(String.valueOf(values),Category.class)).collect(Collectors.toList());
           return categoryList;
        }
             //数据为空,或者不一致,查询数据库
        List<Category> categories=categoryMapper.selectByType(type);
         //缓存到redis中
        Map<String, Category> collectMap = categories.stream()
                .collect(Collectors.toMap(key1 -> key1.getId().toString(), value -> value));
        stringRedisTemplate.opsForHash().putAll(key,collectMap);
        //返回数据
        return categories;
    }

    @Override
    public void changeStatus(Integer status, Long id) {
        categoryMapper.changeStatus(status,id);
    }

}
